package com.carrental.crm.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carrental.common.exception.BusinessException;
import com.carrental.crm.client.VechicleClient;
import com.carrental.crm.config.RabbitMQConfig;
import com.carrental.crm.dto.OrderCreateDTO;
import com.carrental.crm.dto.OrderQueryDTO;
import com.carrental.crm.entity.Order;
import com.carrental.crm.mapper.OrderMapper;
import com.carrental.crm.service.CustomerService;
import com.carrental.crm.service.OrderService;
import com.carrental.crm.vo.CustomerVO;
import com.carrental.crm.vo.OrderVO;
import com.carrental.crm.client.RentalClient;
import com.carrental.common.result.Result;
import com.carrental.crm.vo.VehicleVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 订单服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final CustomerService customerService;
    private final RabbitTemplate rabbitTemplate;
    private final ObjectMapper objectMapper;
    private final VechicleClient vechicleClient;

    @Resource
    private RentalClient rentalClient;

    @Override
    public boolean createOrder(Map<String, Object> params) {
        try {
            log.info("创建订单，参数：{}", params);

            // 获取当前客户ID
            Long customerId = getCurrentCustomerId();
            if (customerId == null) {
                throw new BusinessException("用户未登录，无法创建订单");
            }

            // 构建订单创建DTO
            OrderCreateDTO orderCreateDTO = new OrderCreateDTO();
            orderCreateDTO.setVehicleId(Long.valueOf(params.get("vehicleId").toString()));
            orderCreateDTO.setCustomerId(customerId);
            orderCreateDTO.setStartDate(params.get("startDate").toString());
            orderCreateDTO.setEndDate(params.get("endDate").toString());
            orderCreateDTO.setPickupStoreId(Long.valueOf(params.get("pickupStoreId").toString()));
            orderCreateDTO.setReturnStoreId(Long.valueOf(params.get("returnStoreId").toString()));
            orderCreateDTO.setDuration(Integer.valueOf(params.get("duration").toString()));
            orderCreateDTO.setAmount(new BigDecimal(params.get("amount").toString()));
            orderCreateDTO.setDeposit(new BigDecimal(params.get("deposit").toString()));

            // 生成唯一订单号
            String orderNo = generateOrderNo();
            orderCreateDTO.setOrderNo(orderNo);

            // 发送消息到RabbitMQ
            String message = objectMapper.writeValueAsString(orderCreateDTO);
            rabbitTemplate.convertAndSend(RabbitMQConfig.ORDER_EXCHANGE, RabbitMQConfig.ORDER_CREATE_ROUTING_KEY,
                    message);
            log.info("订单创建消息已发送，订单号：{}", orderNo);

            return true;
        } catch (Exception e) {
            log.error("创建订单失败", e);
            return false;
        }
    }

    /**
     * 生成唯一订单号
     */
    private String generateOrderNo() {
        // 格式：日期时间+6位随机数
        String dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);
        return dateTime + random;
    }

    @Override
    public Page<OrderVO> pageMyOrders(OrderQueryDTO queryDTO) {
        // 获取当前登录客户ID
        Long customerId = getCurrentCustomerId();
        if (customerId == null) {
            throw new BusinessException("未登录");
        }

        log.info("远程调用car-rental服务查询订单列表，客户ID：{}，查询参数：{}", customerId, queryDTO);

        try {
            // 远程调用car-rental服务获取订单列表
            Result<Map<String, Object>> result = rentalClient.pageUserOrders(
                    queryDTO.getPageNum(),
                    queryDTO.getPageSize(),
                    customerId, // 用户ID就是客户ID
                    queryDTO.getStatus(),
                    queryDTO.getStartTime() != null ? queryDTO.getStartTime().toString() : null,
                    queryDTO.getEndTime() != null ? queryDTO.getEndTime().toString() : null);

            if (result.getCode() != 200) {
                log.error("远程调用car-rental服务查询订单列表失败：{}", result.getMessage());
                throw new BusinessException("查询订单失败：" + result.getMessage());
            }

            // 构造返回结果
            Page<OrderVO> voPage = new Page<>();
            Map<String, Object> data = result.getData();

            if (data != null) {
                Object current = data.getOrDefault("current", 1L);
                if (current instanceof Number) {
                    voPage.setCurrent(((Number) current).longValue());
                } else {
                    // 处理非数值类型的情况，例如记录日志或者使用默认值
                    voPage.setCurrent(1L);
                }
                Object current2 = data.getOrDefault("size", 1L);
                if (current2 instanceof Number) {
                    voPage.setSize(((Number) current2).longValue());
                } else {
                    // 处理非数值类型的情况，例如记录日志或者使用默认值
                    voPage.setSize(10L);
                }
                // voPage.setCurrent((Long) data.getOrDefault("current", 1L));

                // voPage.setSize((Long) data.getOrDefault("size", 10L));
                Object current3 = data.getOrDefault("size", 1L);
                if (current3 instanceof Number) {
                    voPage.setTotal(((Number) current3).longValue());
                } else {
                    // 处理非数值类型的情况，例如记录日志或者使用默认值
                    voPage.setTotal(0L);
                }
                // voPage.setTotal((Long) data.getOrDefault("total", 0L));

                // 转换记录
                List<Map<String, Object>> records = (List<Map<String, Object>>) data.getOrDefault("records",
                        new ArrayList<>());
                List<OrderVO> voList = new ArrayList<>();

                for (Map<String, Object> record : records) {
                    OrderVO vo = new OrderVO();
                    // 手动设置属性
                    vo.setId(Long.valueOf(record.getOrDefault("id", 0).toString()));
                    vo.setOrderNo((String) record.getOrDefault("orderNo", ""));
                    vo.setVehicleName((String) record.getOrDefault("vehicleName", ""));
                    Double payAmount = (Double) record.getOrDefault("payAmount", new BigDecimal(0));
                    BigDecimal price = BigDecimal.valueOf(payAmount);
                    vo.setAmount(price);
                    Integer vehicleId = (Integer) record.getOrDefault("vehicleId", "1");
                    Result<VehicleVO> rt = vechicleClient.getVehicleById(vehicleId.longValue());
                    VehicleVO d = rt.getData();
                    vo.setVehicleName(d.getName());
                    vo.setStatus((Integer) record.getOrDefault("status", 0));
                    vo.setStatusName((String) record.getOrDefault("statusName", ""));
                    // 处理日期时间字段
                    if (record.get("createTime") != null) {
                        try {
                            String createTimeStr = record.get("createTime").toString();
                            // 尝试使用DateTimeFormatter解析不同格式的日期
                            DateTimeFormatter formatter;
                            if (createTimeStr.contains("T")) {
                                formatter = DateTimeFormatter.ISO_DATE_TIME;
                            } else if (createTimeStr.contains(" ")) {
                                formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                            } else {
                                formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                            }
                            vo.setOrderTime(LocalDateTime.parse(createTimeStr, formatter));
                        } catch (Exception e) {
                            log.warn("日期解析失败: {}", record.get("createTime"), e);
                            // 设置为当前时间作为后备方案
                            vo.setOrderTime(LocalDateTime.now());
                        }
                    }

                    voList.add(vo);
                }

                voPage.setRecords(voList);
            }

            return voPage;
        } catch (Exception e) {
            log.error("远程调用car-rental服务查询订单列表异常", e);
            throw new BusinessException("查询订单失败，请稍后重试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelOrder(String orderNo) {
        // 获取当前登录客户ID
        Long customerId = getCurrentCustomerId();
        if (customerId == null) {
            throw new BusinessException("未登录");
        }

        log.info("远程调用car-rental服务取消订单，订单号：{}", orderNo);

        try {
            // 先获取订单详情
            Result<Object> orderResult = rentalClient.getOrderByOrderNo(orderNo);
            if (orderResult.getCode() != 200 || orderResult.getData() == null) {
                log.error("远程调用car-rental服务获取订单详情失败：{}", orderResult.getMessage());
                throw new BusinessException("订单不存在或已被删除");
            }

            // 从结果中提取订单ID
            Map<String, Object> orderData = (Map<String, Object>) orderResult.getData();
            Long orderId = Long.valueOf(orderData.getOrDefault("id", 0).toString());

            // 验证订单是否属于当前客户
            Long orderCustomerId = Long.valueOf(orderData.getOrDefault("customerId", 0).toString());
            if (!customerId.equals(orderCustomerId)) {
                throw new BusinessException("只能取消自己的订单");
            }

            // 验证订单状态是否为待支付
            Integer status = (Integer) orderData.getOrDefault("status", 0);
            if (status != 1) {
                throw new BusinessException("只有待支付状态的订单才能取消");
            }

            // 远程调用car-rental服务取消订单
            Result<Boolean> result = rentalClient.cancelOrder(orderId);
            if (result.getCode() != 200 || !Boolean.TRUE.equals(result.getData())) {
                log.error("远程调用car-rental服务取消订单失败：{}", result.getMessage());
                throw new BusinessException("取消订单失败：" + result.getMessage());
            }

            return true;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("远程调用car-rental服务取消订单异常", e);
            throw new BusinessException("取消订单失败，请稍后重试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean payOrder(String orderNo, Integer payType) {
        // 获取当前登录客户ID
        Long customerId = getCurrentCustomerId();
        if (customerId == null) {
            throw new BusinessException("未登录");
        }

        log.info("远程调用car-rental服务支付订单，订单号：{}，支付方式：{}", orderNo, payType);

        try {
            // 先获取订单详情
            Result<Object> orderResult = rentalClient.getOrderByOrderNo(orderNo);
            if (orderResult.getCode() != 200 || orderResult.getData() == null) {
                log.error("远程调用car-rental服务获取订单详情失败：{}", orderResult.getMessage());
                throw new BusinessException("订单不存在或已被删除");
            }

            // 从结果中提取订单ID
            Map<String, Object> orderData = (Map<String, Object>) orderResult.getData();
            Long orderId = Long.valueOf(orderData.getOrDefault("id", 0).toString());

            // 验证订单是否属于当前客户
            Long orderCustomerId = Long.valueOf(orderData.getOrDefault("userId", 0).toString());
            if (!customerId.equals(orderCustomerId)) {
                throw new BusinessException("只能支付自己的订单");
            }

            // 验证订单状态是否为待支付
            Integer status = (Integer) orderData.getOrDefault("status", 0);
            if (status != 1) {
                throw new BusinessException("只有待支付状态的订单才能支付");
            }

            // 远程调用car-rental服务支付订单
            Result<Boolean> result = rentalClient.payOrder(orderId);
            if (result.getCode() != 200 || !Boolean.TRUE.equals(result.getData())) {
                log.error("远程调用car-rental服务支付订单失败：{}", result.getMessage());
                throw new BusinessException("支付订单失败：" + result.getMessage());
            }

            return true;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("远程调用car-rental服务支付订单异常", e);
            throw new BusinessException("支付订单失败，请稍后重试");
        }
    }

    @Override
    public OrderVO getOrderDetail(String orderNo) {
        // 获取当前登录客户ID
        Long customerId = getCurrentCustomerId();
        if (customerId == null) {
            throw new BusinessException("未登录");
        }

        log.info("远程调用car-rental服务获取订单详情，订单号：{}", orderNo);

        try {
            // 远程调用car-rental服务获取订单详情
            Result<Object> result = rentalClient.getOrderByOrderNo(orderNo);
            if (result.getCode() != 200 || result.getData() == null) {
                log.error("远程调用car-rental服务获取订单详情失败：{}", result.getMessage());
                throw new BusinessException("订单不存在或已被删除");
            }

            // 从结果中提取订单数据并转换为VO
            Map<String, Object> orderData = (Map<String, Object>) result.getData();

            // 验证订单是否属于当前客户
            Long orderCustomerId = Long.valueOf(orderData.getOrDefault("userId", 0).toString());
            if (!customerId.equals(orderCustomerId)) {
                throw new BusinessException("只能查看自己的订单");
            }

            OrderVO vo = new OrderVO();
            // 手动设置属性
            vo.setId(Long.valueOf(orderData.getOrDefault("id", 0).toString()));
            vo.setOrderNo((String) orderData.getOrDefault("orderNo", ""));
            Integer vehicleId = (Integer) orderData.getOrDefault("vehicleId", "1");
            Result<VehicleVO> rt = vechicleClient.getVehicleById(vehicleId.longValue());
            vo.setVehicleName(rt.getData().getName());
            Double payAmount = (Double) orderData.getOrDefault("payAmount", new BigDecimal(0));
            BigDecimal price = BigDecimal.valueOf(payAmount);
            vo.setAmount(price);
           // vo.setAmount((java.math.BigDecimal) orderData.getOrDefault("payAmount", new java.math.BigDecimal(0)));
            vo.setStatus((Integer) orderData.getOrDefault("status", 0));
            vo.setStatusName((String) orderData.getOrDefault("statusName", ""));
            // 处理日期时间字段
            if (orderData.get("createTime") != null) {
                try {
                    String createTimeStr = orderData.get("createTime").toString();
                    // 尝试使用DateTimeFormatter解析不同格式的日期
                    DateTimeFormatter formatter;
                    if (createTimeStr.contains("T")) {
                        formatter = DateTimeFormatter.ISO_DATE_TIME;
                    } else if (createTimeStr.contains(" ")) {
                        formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    } else {
                        formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    }
                    vo.setOrderTime(LocalDateTime.parse(createTimeStr, formatter));
                } catch (Exception e) {
                    log.warn("日期解析失败: {}", orderData.get("createTime"), e);
                    // 设置为当前时间作为后备方案
                    vo.setOrderTime(LocalDateTime.now());
                }
            }

            return vo;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("远程调用car-rental服务获取订单详情异常", e);
            throw new BusinessException("获取订单详情失败，请稍后重试");
        }
    }

    /**
     * 获取当前登录客户ID
     *
     * @return 客户ID
     */
    private Long getCurrentCustomerId() {
        // 调用CustomerService中的方法获取当前登录用户ID
        try {
            CustomerVO customerVO = customerService.getCurrentCustomerInfo();
            return customerVO != null ? customerVO.getId() : null;
        } catch (Exception e) {
            log.error("获取当前登录用户ID失败", e);
            return null;
        }
    }
}